package com.xqboss.apps.service.hama;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xqboss.apps.constant.Config;
import com.xqboss.apps.domain.hama.HamaConfigNumber;
import com.xqboss.apps.domain.hama.HamaHelp;
import com.xqboss.apps.enums.hama.HamaConfigNumberPeopleEnum;
import com.xqboss.apps.enums.hama.HamaHelpJoinTypeEnum;
import com.xqboss.apps.mapper.hama.HamaHelpMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.vo.hama.HamaHelpAdminVO;
import com.xqboss.common.core.domain.entity.SysUser;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.AsyncHandlerUtil;
import com.xqboss.common.utils.DateUtils;
import com.xqboss.common.utils.StringUtils;
import com.xqboss.system.service.ISysConfigService;
import com.xqboss.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 助力灵池 服务实现类
 * </p>
 *
 * @author 木鱼
 * @since 2024-02-28
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class HamaHelpService extends ServiceImpl<HamaHelpMapper, HamaHelp> {

    @Resource
    @Lazy
    private ISysUserService sysUserService;

    @Resource
    @Lazy
    private HamaConfigNumberService hamaConfigNumberService;

    @Autowired
    @Lazy
    private ISysConfigService sysConfigService;

    /**
     * 当前用户是否创建过队伍
     *
     * @param userId 用户id
     * @param peopleEnum 人类型
     * @return true-创建过队伍
     */
    public HamaHelpJoinTypeEnum isCreateTeam(Long userId, HamaConfigNumberPeopleEnum peopleEnum) {
        Assert.notNull(userId,()->new ServiceException("用户id不能为空~"));
        Assert.notNull(peopleEnum,()->new ServiceException("人类型不能为空~"));
        Long count = this.lambdaQuery().eq(HamaHelp::getParentUserId, userId).eq(HamaHelp::getIsPeople, peopleEnum).count();
        return count>0?HamaHelpJoinTypeEnum.YES:HamaHelpJoinTypeEnum.NO;
    }

    /**
     * 获取队伍信息
     *
     * @param push 直推/间推  1 直推 2间推
     * @param type 类型 1 全部 2有效 3失效 4-新人 5-全力 6 未实名
     * @param page 分页
     * @param userId 用户id
     * @return 分页数据
     */
    public IPage<HamaHelp> getMyTeam(Integer push,Integer type, Page<HamaHelp> page, Long userId) {
        Assert.notNull(push,()->new ServiceException("类型不能为空~"));
        Assert.notNull(type,()->new ServiceException("类型不能为空~"));
        Assert.notNull(page,()->new ServiceException("分页不能为空~"));
        Assert.notNull(userId,()->new ServiceException("用户id不能为空~"));
        Assert.isTrue(push==1 || push==2,()->new ServiceException("类型不匹配~"));
        Assert.isTrue(type==1 || type==2 || type==3 || type==4 || type==5 || type==6,()->new ServiceException("类型不匹配~"));

        IPage<HamaHelp> iPage = new Page<>();
        if (push == 1) {
            LambdaQueryWrapper<HamaHelp> wrapper = Wrappers.lambdaQuery(HamaHelp.class)
                    .eq(HamaHelp::getParentUserId, userId)
                    .ne(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.ADMIN)
                    .orderByDesc(HamaHelp::getCreateTime);
            iPage = getHamaHelpIPage(type, page, iPage, wrapper);
        }
        if(push==2){
            List<HamaHelp> helps = this.lambdaQuery().select(HamaHelp::getChildUserId).eq(HamaHelp::getParentUserId, userId).ne(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.ADMIN).list();
            if (CollUtil.isNotEmpty(helps)) {
                Set<Long> userIds = helps.stream().map(HamaHelp::getChildUserId).collect(Collectors.toSet());
                LambdaQueryWrapper<HamaHelp> wrapper = Wrappers.lambdaQuery(HamaHelp.class)
                        .in(HamaHelp::getParentUserId, userIds)
                        .ne(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.ADMIN)
                        .orderByDesc(HamaHelp::getCreateTime);
                iPage = getHamaHelpIPage(type, page, iPage, wrapper);
            }
        }
        return iPage;
    }

    /**
     *
     * 筛选 1 全部 2有效 3失效 4-新人 5-全力 6 未实名
     */
    private IPage<HamaHelp> getHamaHelpIPage(Integer type, Page<HamaHelp> page, IPage<HamaHelp> iPage, LambdaQueryWrapper<HamaHelp> wrapper) {
        if(type ==1){
            iPage = this.page(page, wrapper);
        }else if(type ==2){
            iPage = this.page(page, wrapper.gt(HamaHelp::getBasicSpeed, BigDecimal.ZERO));
        }else if(type ==3){
            iPage = this.page(page, wrapper.eq(HamaHelp::getBasicSpeed, BigDecimal.ZERO));
        }else if(type ==4){
            iPage = this.page(page, wrapper.eq(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.NEW));
        }else if(type ==5){
            iPage = this.page(page, wrapper.eq(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.OLD));
        }else if(type ==6){
            iPage = this.page(page, wrapper.eq(HamaHelp::getIsRealName, Boolean.FALSE));
        }
        return iPage;
    }

    /**
     * 实名后开始生产——队员助力
     *
     * @param userId 用户id
     */
    public void startProductionAfterRealName(Long userId){
        Date indexTime = new Date();
        SysUser user = this.sysUserService.getUserInfoOrNull(userId);
        HamaHelp hamaHelp= this.lambdaQuery().eq(HamaHelp::getChildUserId,userId).one();
        if (ObjUtil.isNotEmpty(user) && ObjUtil.isNotEmpty(hamaHelp)) {
            // 没实名且为新人
            if (!hamaHelp.getIsRealName()) {
                Integer day = this.sysConfigService.getValue(Config.Sys.Sport.几天内注册的用户加入运动场算新人);
                boolean isNew = DateUtil.betweenDay(user.getCreateTime(), indexTime, false) <= day;// 3天内注册的用户为新人
                if (isNew) {
                    HamaConfigNumber hamaConfigNumber = this.hamaConfigNumberService.getBasicSpeedNew();
                    Date hireTime= DateUtils.add(indexTime,hamaConfigNumber.getNumber());
                    hamaHelp.setHireTime(hireTime);
                    hamaHelp.setBasicSpeed(hamaConfigNumber.getBasicSpeed());
                    hamaHelp.setIsPeople(HamaConfigNumberPeopleEnum.NEW);
                }else{
                    hamaHelp.setHireTime(null);
                    hamaHelp.setBasicSpeed(BigDecimal.ZERO.stripTrailingZeros());
                    hamaHelp.setIsPeople(HamaConfigNumberPeopleEnum.OLD);
                }
                hamaHelp.setIsRealName(Boolean.TRUE);
                hamaHelp.setStartProductionTime(indexTime);
                this.updateById(hamaHelp);
            }
        }
    }

    public IPage<HamaHelpAdminVO> selectTeamAdmins(Page<HamaHelpAdminVO> page, String search) {
        IPage<HamaHelpAdminVO> iPage = this.getBaseMapper().selectTeamAdmins(page, search);
        if (ObjUtil.isNotEmpty(iPage) && CollUtil.isNotEmpty(iPage.getRecords())) {
            BigDecimal factor = this.sysConfigService.getValue(Config.Sys.Sport.间推助力系数);
            List<Runnable> runnables = new ArrayList<>(iPage.getRecords().size()*6);
            for (HamaHelpAdminVO record : iPage.getRecords()) {
                runnables.add(()->record.setTrueMembers(record.getTrueMembers()+ getDirectMembers(record.getAdminUserId(),true)));
                runnables.add(()->record.setFalseMembers(record.getFalseMembers()+ getDirectMembers(record.getAdminUserId(),false)));
                runnables.add(()->record.setDirectMembers(getBaseMapper().sumManDirect(record.getAdminUserId())));
                runnables.add(()->record.setInDirectMembers(getBaseMapper().sumManInDirect(record.getAdminUserId())));
                runnables.add(()->record.setAirdropSpeed(record.getAirdropSpeed(),getBaseMapper().sumManSpeedSon(record.getAdminUserId()),factor));
                runnables.add(()->record.setAirdropTotal(record.getAirdropTotal(),getBaseMapper().sumManHelpIndirect(record.getAdminUserId())));
            }
            AsyncHandlerUtil.runAllJoin(runnables);
        }
        return iPage;
    }

    /**
     * 获取间推人数
     *
     * @param userId 队长id
     * @param  b true 有效人数 false 无效人数
     * @return 数量
     */
    private Long getDirectMembers(Long userId, boolean b) {
        //直推
        List<HamaHelp> helps = this.lambdaQuery().select(HamaHelp::getChildUserId).eq(HamaHelp::getParentUserId, userId).ne(HamaHelp::getIsPeople,HamaConfigNumberPeopleEnum.ADMIN).list();
        if(CollUtil.isEmpty(helps))return 0L;
        Set<Long> pUid = helps.stream().map(HamaHelp::getChildUserId).filter(Objects::nonNull).collect(Collectors.toSet());
        return this.lambdaQuery().in(HamaHelp::getParentUserId, pUid).apply(b?"basic_speed > 0":"basic_speed = 0").ne(HamaHelp::getIsPeople, HamaConfigNumberPeopleEnum.ADMIN).count();
    }
}